#include <stdio.h>
#include <pthread.h>


//全局变量
//在两个子线程中都要对gNumber进行修改，
//导致出现了bug
//
//此时全局变量成为了临界资源，必须要进行加锁
//不同的子线程要互斥访问临界资源
int gNumber = 0;
int flag = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;

//1号线程当flag为1时，执行加法操作
void * threadFunc1(void *)
{
    int cnt = 100000;
    while(cnt-- > 0) {
        //加锁对临界资源进行保护
        pthread_mutex_lock(&mutex);
        //对条件进行判断
        //注意：使用while防止出现虚假唤醒(异常唤醒)
        while(flag == 0) {
            //当flag值为0时，1号线程等待
            pthread_cond_wait(&cond, &mutex);
        }
        //接下来执行加法操作，默认flag为1
        ++gNumber;
        printf("sub thread 1 do add operation, gNumber:%d\n", gNumber);
        //当执行完加法之后，要修改flag为0
        flag = 0;
        //通知2号线程进行相应的操作
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
    }

    return NULL;
}

//2号线程当flag为0时，执行加法操作
void * threadFunc2(void *)
{
    int cnt = 100000;
    while(cnt-- > 0) {
        pthread_mutex_lock(&mutex);
        while(flag == 1) {
            //当flag值为1时，2号线程等待
            pthread_cond_wait(&cond, &mutex);
        }
        //接下来执行加法操作，默认flag为0
        ++gNumber;
        printf("sub thread 2 do add operation, gNumber:%d\n", gNumber);
        //当执行完加法之后，要修改flag为1
        flag = 1;
        //通知1号线程进行相应的操作
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
    }

    return NULL;
}


int main()
{
    pthread_mutex_init(&mutex, NULL);
    pthread_t pthid1, pthid2;
    pthread_create(&pthid1, NULL, threadFunc1, NULL);
    pthread_create(&pthid2, NULL, threadFunc2, NULL);

    pthread_join(pthid1, NULL);
    pthread_join(pthid2, NULL);

    printf("main thread: gNumber: %d\n", gNumber);

    pthread_mutex_destroy(&mutex);
    return 0;
}

